#include "socket_base.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>

void Socket::Open(const std::string& ip, unsigned short p)
{
    sockaddr_in in;

    in.sin_family = AF_INET;
    in.sin_addr.s_addr = inet_addr(ip.c_str());
    in.sin_port = htons(p);

    _fd = socket(AF_INET, SOCK_STREAM, 0);
    if(-1 == _fd) {
        printf("Error open socket\n");
        return;
    }
    int ret = connect(_fd, (sockaddr*)&in, sizeof(sockaddr_in));
    if(-1 == ret) {
        printf("Error connect to server\n");
        return;
    }
}

void Socket::Send(SharedBuffer data)
{
    l64 len = data->Length();
    int ns = send(_fd, (void*)&len, sizeof(l64), 0);
    if(ns < 0) {
        printf("Error send data length(error:%d)\n", errno);
        return;
    }

    len = 0;
    do
    {
        const char* sdata = data->Get() + len;
        int ns = send(_fd, sdata, data->Length() - len, 0);
        if(ns == 0) break;
        else if(-1 == ns) {
            if(errno == EWOULDBLOCK || errno == EAGAIN)
                continue;
            else 
                break;
        }
        len += ns;
    } while (len < data->Length());
}

Socket* SocketMGR::NewConnect(const std::string& ip, unsigned short p)
{
    Socket* s = new Socket();
    s->Open(ip, p);

    return s;
}

void SocketMGR::Insert(const std::string& label, int s)
{
    _fds.insert(std::make_pair(label, new Socket(s)));
}

Socket* SocketMGR::Get(const std::string& label)
{
    if(_fds.find(label) != _fds.end())
        return _fds[label];

    return s_invalid_socket;
}
